home *** CD-ROM | disk | FTP | other *** search
- ;;; installed-scm-file
-
- ;;;; Copyright (C) 1996, 1998, 2001 Free Software Foundation, Inc.
- ;;;;
- ;;;; This program is free software; you can redistribute it and/or modify
- ;;;; it under the terms of the GNU General Public License as published by
- ;;;; the Free Software Foundation; either version 2, or (at your option)
- ;;;; any later version.
- ;;;;
- ;;;; This program is distributed in the hope that it will be useful,
- ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
- ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ;;;; GNU General Public License for more details.
- ;;;;
- ;;;; You should have received a copy of the GNU General Public License
- ;;;; along with this software; see the file COPYING. If not, write to
- ;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- ;;;; Boston, MA 02111-1307 USA
- ;;;;
- ;;;; As a special exception, the Free Software Foundation gives permission
- ;;;; for additional uses of the text contained in its release of GUILE.
- ;;;;
- ;;;; The exception is that, if you link the GUILE library with other files
- ;;;; to produce an executable, this does not by itself cause the
- ;;;; resulting executable to be covered by the GNU General Public License.
- ;;;; Your use of that executable is in no way restricted on account of
- ;;;; linking the GUILE library code into it.
- ;;;;
- ;;;; This exception does not however invalidate any other reasons why
- ;;;; the executable file might be covered by the GNU General Public License.
- ;;;;
- ;;;; This exception applies only to the code released by the
- ;;;; Free Software Foundation under the name GUILE. If you copy
- ;;;; code from other Free Software Foundation releases into a copy of
- ;;;; GUILE, as the General Public License permits, the exception does
- ;;;; not apply to the code that you add in this way. To avoid misleading
- ;;;; anyone as to the status of such modified files, you must delete
- ;;;; this exception notice from them.
- ;;;;
- ;;;; If you write modifications of your own for GUILE, it is your choice
- ;;;; whether to permit this exception to apply to your modifications.
- ;;;; If you do not wish that, delete this exception notice.
- ;;;;
-
-
-
- (define-module (ice-9 lineio)
- :use-module (ice-9 readline)
- :export (unread-string read-string lineio-port?
- make-line-buffering-input-port))
-
-
- ;;; {Line Buffering Input Ports}
- ;;;
- ;;; [This is a work-around to get past certain deficiencies in the capabilities
- ;;; of ports. Eventually, ports should be fixed and this module nuked.]
- ;;;
- ;;; A line buffering input port supports:
- ;;;
- ;;; read-string which returns the next line of input
- ;;; unread-string which pushes a line back onto the stream
- ;;;
- ;;; The implementation of unread-string is kind of limited; it doesn't
- ;;; interact properly with unread-char, or any of the other port
- ;;; reading functions. Only read-string will get you back the things that
- ;;; unread-string accepts.
- ;;;
- ;;; Normally a "line" is all characters up to and including a newline.
- ;;; If lines are put back using unread-string, they can be broken arbitrarily
- ;;; -- that is, read-string returns strings passed to unread-string (or
- ;;; shared substrings of them).
- ;;;
-
- ;; read-string port
- ;; unread-string port str
- ;; Read (or buffer) a line from PORT.
- ;;
- ;; Not all ports support these functions -- only those with
- ;; 'unread-string and 'read-string properties, bound to hooks
- ;; implementing these functions.
- ;;
- (define (unread-string str line-buffering-input-port)
- ((object-property line-buffering-input-port 'unread-string) str))
-
- ;;
- (define (read-string line-buffering-input-port)
- ((object-property line-buffering-input-port 'read-string)))
-
-
- (define (lineio-port? port)
- (not (not (object-property port 'read-string))))
-
- ;; make-line-buffering-input-port port
- ;; Return a wrapper for PORT. The wrapper handles read-string/unread-string.
- ;;
- ;; The port returned by this function reads newline terminated lines from PORT.
- ;; It buffers these characters internally, and parsels them out via calls
- ;; to read-char, read-string, and unread-string.
- ;;
-
- (define (make-line-buffering-input-port underlying-port)
- (let* (;; buffers - a list of strings put back by unread-string or cached
- ;; using read-line.
- ;;
- (buffers '())
-
- ;; getc - return the next character from a buffer or from the underlying
- ;; port.
- ;;
- (getc (lambda ()
- (if (not buffers)
- (read-char underlying-port)
- (let ((c (string-ref (car buffers))))
- (if (= 1 (string-length (car buffers)))
- (set! buffers (cdr buffers))
- (set-car! buffers (substring (car buffers) 1)))
- c))))
-
- (propogate-close (lambda () (close-port underlying-port)))
-
- (self (make-soft-port (vector #f #f #f getc propogate-close) "r"))
-
- (unread-string (lambda (str)
- (and (< 0 (string-length str))
- (set! buffers (cons str buffers)))))
-
- (read-string (lambda ()
- (cond
- ((not (null? buffers))
- (let ((answer (car buffers)))
- (set! buffers (cdr buffers))
- answer))
- (else
- (read-line underlying-port 'concat)))))) ;handle-newline->concat
-
- (set-object-property! self 'unread-string unread-string)
- (set-object-property! self 'read-string read-string)
- self))
-
-
-